package se.webbzon.boltzmann.editor.component.sequence;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.Collection;

import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

import se.webbzon.boltzmann.editor.component.AbstractComponent;
import se.webbzon.boltzmann.editor.component.sequence.factory.AbstractSequenceRowFactory;
import se.webbzon.boltzmann.editor.component.sequence.factory.SequenceRowFactoryGroup;
import se.webbzon.boltzmann.editor.list.SortedListModel;
import se.webbzon.boltzmann.game.sequence.builder.AbstractSequenceRow;
import se.webbzon.boltzmann.game.sequence.builder.SequenceBuilder;

public class RowFactoryPanel extends AbstractComponent {
	
	// Auto generated serial version UID
	private static final long serialVersionUID = -4116368579175101582L;

	// The sequence builder associated with this panel
	private final SequenceBuilder builder;
	
	// The lists of this panel
	private final JList<AbstractSequenceRowFactory> factories;
	
	// A collection of all listener to this panel
	private final Collection<RowFactoryListener> listeners;
	
	/*============================================================
	Constructors
	============================================================*/

	public RowFactoryPanel(	SequenceBuilder builder,
							SequenceRowFactoryGroup factoryGroup) {
		super("Sequence Row Factories");
		this.builder = builder;
		listeners = new ArrayList<RowFactoryListener>();
		setLayout(new BorderLayout());
		
		// Create factory list model
		SortedListModel<AbstractSequenceRowFactory> factoryModel = 
				new SortedListModel<AbstractSequenceRowFactory>(
						AbstractSequenceRowFactory.class,
						factoryGroup.getFactories());
		
		// Create the content of this panel	
		add(new JLabel("Row Factories"),BorderLayout.NORTH);
		
		factories = new JList<AbstractSequenceRowFactory>(factoryModel);
		JScrollPane factoryScrollPane = new JScrollPane(factories);
		//factoryScrollPane.setPreferredSize(dimension);
		add(factoryScrollPane,BorderLayout.CENTER);

		JPanel factoryButtonPanel = new JPanel();
		factoryButtonPanel.setLayout(new BorderLayout());
		factoryButtonPanel.add(new JButton(new AddRowAction()),BorderLayout.WEST);
		factoryButtonPanel.add(new JButton(new InsertRowAction()),BorderLayout.EAST);
		add(factoryButtonPanel,BorderLayout.SOUTH);
	}
	
	/*============================================================
	Public Methods
	============================================================*/
	
	/** Adds a listener to this row factory panel. **/
	public boolean addListener(RowFactoryListener listener) {
		return listeners.add(listener);
	}
	
	/** Removes a listener from this row factory panel. **/
	public boolean removeListener(RowFactoryListener listener) {
		return listeners.remove(listener);
	}
	
	/** Clears all the listeners in this row factory panel. **/
	public void clearListener() {
		listeners.clear();
	}
	
	/*============================================================
	Private Classes
	============================================================*/
	
	/** An abstract action used for the add row button. **/
	private final class AddRowAction extends AbstractAction {
		
		// Auto generated serial version UID
		private static final long serialVersionUID = 3640092657895262197L;
		
		/*============================================================
		Constructor
		============================================================*/

		public AddRowAction() {
			putValue(AbstractAction.NAME,"Add");
		}

		/*============================================================
		Public Methods
		============================================================*/
		
		@Override public void actionPerformed(ActionEvent event) {
			AbstractSequenceRowFactory factory = factories.getSelectedValue();
			if (factory != null) {
				AbstractSequenceRow row = factory.makeNew(builder);
				for (RowFactoryListener listener : listeners.toArray(new RowFactoryListener[0]))
					listener.addRow(RowFactoryPanel.this, row);
			}
		}
		
	}
	
	/** An abstract action used for the insert row button. **/
	private final class InsertRowAction extends AbstractAction {
		
		// Auto generated serial version UID
		private static final long serialVersionUID = 88988426585779180L;
		
		/*============================================================
		Constructor
		============================================================*/

		public InsertRowAction() {
			putValue(AbstractAction.NAME,"Insert");
		}

		/*============================================================
		Public Methods
		============================================================*/
		
		@Override public void actionPerformed(ActionEvent arg0) {
			AbstractSequenceRowFactory factory = factories.getSelectedValue();
			if (factory != null) {
				AbstractSequenceRow row = factory.makeNew(builder);
				for (RowFactoryListener listener : listeners.toArray(new RowFactoryListener[0]))
					listener.insertRow(RowFactoryPanel.this, row);
			}
		}
		
	}

}
